<template>
  <span @click="doOpenDialog">
    <slot>
      <div v-if="multiple" class="dmform-listeditor" :class="{'no-border':noBorder}" style="padding-right: 20px;">
        <span v-if="displayRows.length == 0" class="global-gray">{{placeholder}}</span>
        <a-tag v-for="(row, index) in displayRows" :key="index" color="blue" :visible="true">
         {{row.name}}
        </a-tag>
        <a-icon v-if="displayRows.length" type="close-circle" class="_clear" @click.native.stop="doClear" />
      </div>
      <div v-else class="dmform-listeditor" :class="{'no-border':noBorder}" style="padding-right: 20px;">
        <span v-if="displayRows.length == 0" class="global-gray">{{placeholder}}</span>
        <span v-for="(row, index) in displayRows" :key="index">
         {{row.name}}
        </span>
        <a-icon v-if="displayRows.length" type="close-circle" class="_clear" @click.native.stop="doClear" />
      </div>
    </slot>
  </span>
</template>
<script>
import {Modal} from 'ant-design-vue'
import lodash from 'lodash'
export default {
  name: 'TreeSelectDialog',
  props: {
    /**
     * 数据KEY。格式：
     * 单选：字符或数字
     * 多选：字符或数字数组
     */
    value: [Array, String, Number],
    /**
     * 数据对象：可以回写选中的值，格式：
     * 单选对象：{id:String, name:String}
     * 多选数组：[{id:String, name:String}, ...]
     */
    data: [Array, Object],
    dataUrl: String,
    queryParams: Object,
    multiple: Boolean,
    emptyText: String,
    placeholder: String,
    width: Number,
    height: Number,
    noBorder: Boolean,
    maxTagPlaceholder: Number,
    mask: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      currKeys: undefined, // current value
      currRows: undefined, // current data
      displayRows: [],
      dialog: null,
      init: window.$debounce(this.initMe, 300),
      updateDisplayRows: window.$debounce(this._updateDisplayRows, 300),
    }
  },
  mounted() {
    this.init()
  },
  watch: {
    value() {
      this.parseValue()
    },
    data: {
      handler: function() {
        this.parseData()
      },
      deep: true
    },
    currRows: {
      handler: function() {
        this.updateDisplayRows()
      },
      deep: true
    }
  },
  methods: {
    initMe() {
      this.parseValue()
      this.parseData()
      this.updateDisplayRows()
    },
    parseValue() {
      if (!this.currKeys && !this.value) {
        return
      }
      if (this.currKeys === this.value) {
        return
      }
      // console.log('TreeSelectDialog/parseValue: value=', JSON.stringify(this.value))
      this.currKeys = this.value
      if (!this.data) {
        if (lodash.isArray(this.currKeys)) {
          this.currRows = []
          this.currKeys.forEach((key) => {
            this.currRows.push({
              id: key,
              name: key
            })
          })
        } else if (this.currKeys) {
          this.currRows = {
            id: this.currKeys,
            name: this.currKeys
          }
        } else {
          this.currRows = []
        }
      }
    },
    parseData() {
      if (!this.currRows && !this.data) {
        return
      }
      if (this.currRows === this.data) {
        return
      }
      // console.log('TreeSelectDialog/parseData: data=', JSON.stringify(this.data))
      this.currRows = this.data || (this.multiple ? [] : {})
      if (lodash.isArray(this.currRows)) {
        this.currKeys = []
        this.currRows.forEach(row => {
          this.currKeys.push(row.id)
        })
      } else {
        this.currKeys = this.currRows.id
      }
    },
    _updateDisplayRows() {
      this.displayRows = this.getDisplayRows()
      // console.log('TreeSelectDialog/_updateDisplayRows: displayRows=', JSON.stringify(this.displayRows))
    },
    getDisplayRows() {
      // console.log('TreeSelectDialog/getDisplayRows: ', JSON.stringify(this.currRows))
      if (this.maxTagPlaceholder) {
        let returnRows = []
        this.currRows.forEach((row, idx) => {
          if (idx < this.maxTagPlaceholder) {
            returnRows.push(row)
          }
        })
        const count = this.currRows.length - this.maxTagPlaceholder
        if (count > 0) {
          returnRows.push({
            name: '...' + count
          })
        }
        return returnRows
      } else {
        if (lodash.isArray(this.currRows)) {
          return lodash.clone(this.currRows)
        } else if (this.currRows) {
          if (this.currRows.id && this.currRows.name) {
            return [this.currRows]
          } else if (this.currRows.id) {
            return [{
              id: this.currRows.id,
              name: this.currRows.id,
            }]
          } else if (this.currRows.name) {
            return [{
              id: '',
              name: this.currRows.id,
            }]
          } else {
            return []
          }
        } else {
          return []
        }
      }
    },
    doOpenDialog() {
      let self = this
      let clazz = 'dmform-modal'
      // if (!this.$slots.default) {
      //   clazz = 'dmform-modal dmform-modal-onlybody'
      // }
      this.modal = Modal.info({
        class: clazz,
        width: this.width || 400,
        maskClosable: true,
        mask: this.mask,
        okText: '确定',
        onOk() {
          self.doOk()
        },
        onCancel() {
          self.doClose()
        },
        content: h => h('TreeSelect', {
          props: {
            value: this.currKeys,
            dataUrl: this.dataUrl,
            queryParams: this.queryParams,
            multiple: this.multiple,
            emptyText: this.emptyText,
            height: this.height || 300
          },
          on: {
            onCheckChange: this.doCheckChange,
            onChange: this.doChange
          }
        }),
      })
    },
    doClear() {
      this.currKeys = []
      this.currRows = []
      this.$emit('input', null)
      this.$emit('onChange', {
        keys: null,
        rows: null
      })
    },
    doChange(keys, rows) {
      // console.log('doChange: keys = %s, rows = %s', JSON.stringify(keys), JSON.stringify(rows))
      this.currKeys = keys
      if (!this.multiple) {
        if (this.currRows) {
          lodash.assign(this.currRows, rows)
        } else {
          this.currRows = rows
        }
      } else {
        if (this.currRows) {
          lodash.assign(this.currRows, rows)
        } else {
          this.currRows = rows
        }
      }
      this.updateDisplayRows()
      // console.log('doChange: currKeys = %s, currRows = %s', JSON.stringify(this.currKeys), JSON.stringify(this.currRows))
      // console.log('doChange: currKeys == keys, currRows = rows', this.currKeys === keys, this.currRows === rows)
      this.$emit('input', this.currKeys)
      this.$emit('onChange', {
        keys: keys,
        rows: rows
      })
    },
    doCheckChange(data, checked) {
      this.$emit('onCheckChange', data, checked)
    },
    doOk() {
      // console.log('doOk: currKeys = ', JSON.stringify(this.currKeys))
      // console.log('doOk: currRows = ', this.currRows.length)
      // this.$emit('input', this.currKeys)
      this.$emit('onConfirm', {
        keys: this.currKeys,
        rows: this.currRows
      })
      if (this.modal) {
        this.modal.destroy()
      }
    },
    doClose() {
      // console.log('doClose...')
      this.$emit('onCancel')
      if (this.modal) {
        this.modal.destroy()
      }
    }
  }
}
</script>
